package com.example.demo1.temp;

import org.junit.Test;

import java.util.Arrays;
import java.util.Comparator;
import java.util.function.*;

/**
 * @ClassName: methodRefTest
 * @Description: 方法引用和构造器引用
 * @Version: v1.0.0
 * @Author: tang
 * @Date: 2021-10-26
 * Modification History:
 * Date             Author      Version     Description
 * -------------------------------------------------------------
 *   2021-10-26      tang        v1.0.0      创建
 */
public class MethodRefTest {
    /**
    * 方法引用:若lambda体中的内容已经有方法已经实现，我们可以使用方法引用（可以理解为方法引用是Lambda表达式的另一种表现形式）
    *
    * 主要三种语法格式：
    *
    *  1 对象::实例方法名
     *
     * 2 类::静态方法名
     *
     * 3 类::实例方法名
     *
     * （1）lambda体中调用方法的参数列表与返回类型，要与函数式接口中抽象方法的函数列表和返回值类型保持一致
     * （2）若Lambda体参数列表中第一个参数是实例方法的调用者 ，而第二个方式是实例方法的参数时，可以使用 ClassName::method
     *
     *
    * */


    /**
     * 对象::实例方法名
     * @Author tang
     * @Date 2021/10/26
     **/
    @Test
    public void test1(){
        Consumer<String> con1 = (x)-> System.out.println(x);
        con1.accept("原始方式");

        Consumer<String> con2 = System.out::println;
        con2.accept("方法引用");
    }
    /**
     * 对象::实例方法名
     * @Author tang
     * @Date 2021/10/26
     **/
    @Test
    public void test2(){
        Comparator<Integer> con = (x,y)->Integer.compare(x,y);
        System.out.println("3比5大"+con.compare(3,5));
        Comparator<Integer> con2 = Integer::compare;
        System.out.println("5比8大"+con.compare(5,8));
    }
    /**
     * 类::实例方法名
     * @Author tang
     * @Date 2021/10/26
     **/
    @Test
    public void test3(){
        BiPredicate<String,String> biPredicate = (x,y)->x.equals(y);

        BiPredicate<String,String> biPredicate2 = String::equals;

    }
    /**
     * 构造器引用
     *
     * 格式：
     * ClassName::new
     * 注意：需要调用的构造器参数列表要与函数式接口中抽象方法的参数列表保持一致
     * */
    @Test
    public void test4(){
        Supplier<Person> sp = ()->new Person();
        System.out.println(sp.get());
        Supplier<Person> sp2 = Person::new;
        System.out.println(sp2.get());
    }

    @Test
    public void test5(){
        Function<Integer,Person> p = (x)->new Person(x);
        System.out.println(p.apply(16));
        Function<Integer,Person> p2 = Person::new;
        System.out.println(p2.apply(18));
    }

    /**
     * 数组引用
     *
     * 格式：
     * 类名[]::new
     * 注意：需要调用的构造器参数列表要与函数式接口中抽象方法的参数列表保持一致
     * */
    @Test
    public void test6(){
        Function<Integer,String[]> fun = (x)->new String[x];
        String[] apply = fun.apply(10);
        System.out.println(Arrays.toString(apply));
        Function<Integer,String[]> fun2 = String[]::new;
        String[] apply1 = fun2.apply(12);
        System.out.println(Arrays.toString(apply1));


    }
}
